﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.Shell.Interop;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.TextManager.Interop;

namespace TFDP.VsPackage.Services
{
    public interface IFileChangeService
    {
        void BeforeFileChange(string fileName);
        void AfterFileChange(string fileName);
    }

    internal class FileChangeService : IFileChangeService
    {
        private IVsRunningDocumentTable rdt;

        public FileChangeService(IVsRunningDocumentTable rdt)
        {
            this.rdt = rdt;
        }

        public void BeforeFileChange(string fileName)
        {
            IVsFileChangeEx fcx = (IVsFileChangeEx)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsFileChangeEx));
            fcx.IgnoreFile(0, fileName, 1);
        }

        public void AfterFileChange(string fileName)
        {
            IVsFileChangeEx fcx = (IVsFileChangeEx)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsFileChangeEx));
            fcx.SyncFile(fileName);
            fcx.IgnoreFile(0, fileName, 0);

            VsTextBuffer buffer = GetVsTextBuffer(fileName);
            if (buffer != null)
            {
                IVsPersistDocData pdd = (IVsPersistDocData)buffer;
                pdd.ReloadDocData((uint)_VSRELOADDOCDATA.RDD_IgnoreNextFileChange);
            }
        }

        private VsTextBuffer GetVsTextBuffer(string fileName)
        {
            uint dwRDTLockType = (uint)_VSRDTFLAGS.RDT_NoLock;
            string pszMkDocument = fileName;
            IVsHierarchy ppHier;
            uint pitemid;
            IntPtr ppunkDocData;
            uint pdwCookie;

            rdt.FindAndLockDocument(
                dwRDTLockType,
                pszMkDocument,
                out ppHier,
                out pitemid,
                out ppunkDocData,
                out pdwCookie
            );

            if (ppunkDocData != IntPtr.Zero)
            {
                VsTextBuffer buffer = (VsTextBuffer)Marshal.GetObjectForIUnknown(ppunkDocData);
                return buffer;
            }

            return null;
        }

    }
}
